package oauth

// 微信第三方登录
import (
	"errors"
	"net/url"
	"encoding/json"
	"gowechat/config"
	"gowechat/gateway"
)

type errorResponse struct {
	ErrCode int    `json:"errcode"`
	ErrMsg  string `json:"errmsg"`
}
type AccessTokenResponse struct {
	errorResponse
	AccessToken  string `json:"access_token"`
	ExpiresIn    int    `json:"expires_in"`
	RefreshToken string `json:"refresh_token"`
	OpenId       string `json:"openid"`
	Scope        string `json:"scope"`
	UnionId      string `json:"unionid"`
}
type RefreshTokenResponse struct {
	errorResponse
	AccessToken  string `json:"access_token"`
	ExpiresIn    int    `json:"expires_in"`
	RefreshToken string `json:"refresh_token"`
	OpenId       string `json:"openid"`
	Scope        string `json:"scope"`
}
type UserInfoResponse struct {
	errorResponse
	OpenId     string   `json:"openid"`
	Nickname   string   `json:"nickname"`
	Sex        int8     `json:"sex"`
	Province   string   `json:"province"`
	City       string   `json:"city"`
	Country    string   `json:"country"`
	HeadImgUrl string   `json:"headimgurl"`
	Privilege  []string `json:"privilege"`
	UnionId    string   `json:"unionid"`
}

// Access Token请求
func AccessTokenRequest(appId string, code string) (error, *AccessTokenResponse) {
	if appId == "" {
		return errors.New("AppId Is Empty "), nil
	}
	if code == "" {
		return errors.New("Code Is Empty "), nil
	}
	err, configUnit := config.Get(appId)
	if err != nil {
		return err, nil
	}
	var api = "https://api.weixin.qq.com/sns/oauth2/access_token"
	query := url.Values{}
	query.Add("appid", configUnit.AppID)
	query.Add("secret", configUnit.AppSecret)
	query.Add("code", code)
	query.Add("grant_type", "authorization_code")
	api = api + "?" + query.Encode()
	err, body := gateway.Get(api)
	if err != nil {
		return err, nil
	}
	accessTokenResponse := &AccessTokenResponse{}
	err = json.Unmarshal(body, accessTokenResponse)
	if err != nil {
		return err, accessTokenResponse
	}
	if accessTokenResponse.ErrCode != 0 {
		return errors.New(accessTokenResponse.ErrMsg), accessTokenResponse
	}
	return nil, accessTokenResponse
}

// RefreshToken请求
func RefreshTokenRequest(appId string, refreshToken string) (error, *RefreshTokenResponse) {
	if appId == "" {
		return errors.New("AppId Is Empty "), nil
	}
	if refreshToken == "" {
		return errors.New("RefreshToken Is Empty "), nil
	}
	err, configUnit := config.Get(appId)
	if err != nil {
		return err, nil
	}
	var api = "https://api.weixin.qq.com/sns/oauth2/refresh_token"
	query := url.Values{}
	query.Add("appid", configUnit.AppID)
	query.Add("grant_type", "refresh_token")
	query.Add("refresh_token", refreshToken)
	api = api + "?" + query.Encode()
	err, body := gateway.Get(api)
	if err != nil {
		return err, nil
	}
	refreshTokenResponse := &RefreshTokenResponse{}
	err = json.Unmarshal(body, refreshTokenResponse)
	if err != nil {
		return err, refreshTokenResponse
	}
	if refreshTokenResponse.ErrCode != 0 {
		return errors.New(refreshTokenResponse.ErrMsg), refreshTokenResponse
	}
	return nil, refreshTokenResponse
}

// 检验授权凭证（access_token）是否有效
func AccessTokenCheck(accessToken string, openId string) error {
	if accessToken == "" {
		return errors.New("accessToken Is Empty ")
	}
	if openId == "" {
		return errors.New("openId Is Empty ")
	}
	var api = "https://api.weixin.qq.com/sns/auth"
	query := url.Values{}
	query.Add("access_token", accessToken)
	query.Add("openid", openId)
	api = api + "?" + query.Encode()
	err, body := gateway.Get(api)
	if err != nil {
		return err
	}
	errInfo := &errorResponse{}
	err = json.Unmarshal(body, errInfo)
	if err != nil {
		return err
	}
	if errInfo.ErrCode != 0 {
		return errors.New(errInfo.ErrMsg)
	}
	return nil
}

// 此接口用于获取用户个人信息
func UserInfo(accessToken string, openId string) (error, *UserInfoResponse) {
	if accessToken == "" {
		return errors.New("accessToken Is Empty "), nil
	}
	if openId == "" {
		return errors.New("openId Is Empty "), nil
	}
	var api = "https://api.weixin.qq.com/sns/userinfo"
	query := url.Values{}
	query.Add("access_token", accessToken)
	query.Add("openid", openId)
	api = api + "?" + query.Encode()
	err, body := gateway.Get(api)
	if err != nil {
		return err, nil
	}
	userInfo := &UserInfoResponse{}
	err = json.Unmarshal(body, userInfo)
	if err != nil {
		return err, nil
	}
	if userInfo.ErrCode != 0 {
		return errors.New(userInfo.ErrMsg), nil
	}
	return nil, userInfo
}
